package com.tanjun.gateway.gatewayservice.config;

import cn.dev33.satoken.reactor.context.SaReactorSyncHolder;
import cn.dev33.satoken.router.SaRouter;
import cn.hutool.core.net.URLEncodeUtil;
import com.alibaba.fastjson2.JSONObject;
import com.tanjun.common.constants.HeaderConstant;
import com.tanjun.common.constants.UrlConstant;
import com.tanjun.common.enums.user.UserTypeEnum;
import com.tanjun.common.exception.BizException;
import com.tanjun.common.model.LoginUserInfo;
import com.tanjun.gateway.gatewayservice.service.UserLoginService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Stream;

/**
 * 网关路由的时候会调用该方法 如：/user-service/admin/user
 *
 */
@Slf4j
@Configuration
public class GateWayHeaderFilter implements GlobalFilter, Ordered {
    @Autowired
    private UserLoginService userLoginService;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        SaReactorSyncHolder.setContext(exchange);
        String url = exchange.getRequest().getURI().getPath();
        log.info("进入获取用户过滤器:{}",exchange.getRequest().getURI().getPath());
        // 从当前请求中获取网关传递的头部
        if(Stream.of("/*"+UrlConstant.URL_USER.INNER+"/*"+UrlConstant.URL_AUTH.OPEN+"/**")
                .anyMatch(pattern-> SaRouter.isMatch(pattern,url))){
            return chain.filter(exchange);
        }
        List<String> userRoles = null;
        List<String> userPermissions = null;
        LoginUserInfo loginUserInfo = null;

        if(SaRouter.isMatch("/*"+UrlConstant.URL_USER.ADMIN+"/**",url)){
            if(StpUtilKit.adminStpLogic.isLogin()) {
                loginUserInfo = userLoginService.getLoginUserInfo(UserTypeEnum.ADMIN, StpUtilKit.adminStpLogic.getLoginIdAsLong());
                userRoles= StpUtilKit.adminStpLogic.getRoleList();
                userPermissions = StpUtilKit.adminStpLogic.getPermissionList();
            }
        }
        else if(SaRouter.isMatch("/*"+UrlConstant.URL_USER.MEM+"/**",url)){
            if(StpUtilKit.memStpLogic.isLogin()){
                loginUserInfo = userLoginService.getLoginUserInfo(UserTypeEnum.MEM,StpUtilKit.memStpLogic.getLoginIdAsLong());
            }
        }
        else {
            throw new BizException("用户类型错误");
        }
        log.info("[gateway add header],userInfo:{},userRoles:{},userPermission:{}",loginUserInfo,userRoles,userPermissions);
        // 将头部添加到请求中
        String loginTerminal="";
        if(exchange.getRequest().getHeaders().getFirst(HeaderConstant.LOGIN_TERMINAL) != null){
            loginTerminal=exchange.getRequest().getHeaders().getFirst(HeaderConstant.LOGIN_TERMINAL);
        }
        ServerHttpRequest modifiedRequest = exchange.getRequest().mutate()
                .header(HeaderConstant.USER_INFO, URLEncodeUtil.encode(getUserInfoJson(loginUserInfo),StandardCharsets.UTF_8))
                .header(HeaderConstant.USER_ROLES,userRoles!=null?String.join(",", userRoles):"")
                .header(HeaderConstant.USER_TYPE,loginUserInfo!=null?loginUserInfo.getUserType().getCode():"")
                .header(HeaderConstant.ADMIN_USER_TYPE,loginUserInfo!=null&&loginUserInfo.getAdminUserTypeEnum()!=null?
                        loginUserInfo.getAdminUserTypeEnum().getValue().toString():null)
                .header(HeaderConstant.USER_PERMISSION,getPermission(userPermissions))
                .header(HeaderConstant.LOGIN_TERMINAL,loginTerminal)
                .build();

        return chain.filter(exchange.mutate().request(modifiedRequest).build())
                .then(Mono.fromRunnable(()->{
                }));

    }

    @Override
    public int getOrder() {
        return HIGHEST_PRECEDENCE;
    }


    private String getPermission(List<String> permissions){
        if(permissions==null){
            return "";
        }
        return String.join(",", permissions);
    }

    private String getUserInfoJson(LoginUserInfo loginUserInfo){
        if(loginUserInfo==null){
            return "";
        }
        return JSONObject.toJSONString(loginUserInfo);
    }


}
